package session;

import Interface.Entity;
import storage.EntityStorage;

/**
 * Developed for NTT - All is an Entity
 * Questa classe è ò'implementazione di Entity per il sistema session
 * @author Alessandro Pollace
 * @version 0.1
 */
public class EntitySession extends EntityStorage implements Entity {

    /***** CONSTRUCTOR *****/
    /**
     * Costruttore della classe EntitySession
     * @param entityName Nome dell'entity da caricare
     * @throws Exception Entity non trovata
     */
    public EntitySession(String entityName) throws Exception {
        super(entityName);
    }

    /**
     * Questo metodo controlla se l'utente loggato in questo momento è il proprietario di questa entity
     * @return TRUE = è il proprietario, FALSE = Non è il Proprietario
     */
    private boolean isOwner() {
        String proprietario = this.getOwner();
        if (proprietario == null){
            return false;
        }
        if (proprietario.equals(super.user)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Controlla una volta presi in input un gruppo di permessi se l'utente che è loggato in questo momento rientra nei permessi passati in input
     * @param permessi Array dei permessi da verificare
     * @return TRUE = l'utente ha i permessi, FALSE = l'utente non ha i permessi
     */
    private boolean isPermits(String permessi[]) {
        for (int i = 0; i < permessi.length; i++) {
            if (permessi[i].equals(this.group)) {
                //L'utente appartiene al gruppo che ha i permessi
                return true;
            }
            if (permessi[i].equals("all")) {
                //tutti hanno il permesso di visione
                return true;
            }
            if (permessi[i].equals("owner")) {
                if (isOwner()) {
                    //il proprietario ha il permesso
                    return true;
                }
            }
            if (permessi[i].equals("registered")) {
                if (!super.user.equals("anonimous")) {
                    //Gli utenti registrati hanno il permesso
                    return true;
                }
            }
            if (permessi[i].equals("anonimous")) {
                if (super.user.equals("anonimous")) {
                    //gli utenti anonimi hanno il permesso
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Ritorna un valore booleano che indica se l'attributo chiamato per nome è leggibile dall'utente attualmente loggato
     * @param attributeName nome dell'attributo
     * @return TRUE = leggibile; FALSE = Non leggibile
     * @throws Exception Attributo non esistente
     */
    public boolean isPermitsRead(String attributeName) throws Exception {
        String permessi[] = this.getAttributePermitsReading(attributeName);
        return this.isPermits(permessi);
    }

    /**
     * Ritorna un valore booleano che indica se l'attributo chiamato per nome è modificabile dall'utente attualmente loggato
     * @param attributeName nome dell'attributo
     * @return TRUE = modificabile; FALSE = Non modificabile
     * @throws Exception Attributo non esistente
     */
    public boolean isPermitsModify(String attributeName) throws Exception {
        String permessi[] = this.getAttributePermitsModify(attributeName);
        return this.isPermits(permessi);
    }

    /**
     * Ritorna il valore di un attributo chiamato per nome solo se l'utente ha i permessi di lettura
     * @param AttributeName Nome dell'attributo
     * @return Valore
     * @throws Exception Attributo non trovato
     */
    @Override
    public Object getAttributeValue(String AttributeName) throws Exception {
        if (this.isPermitsRead(AttributeName)) {
            return super.getAttributeValue(AttributeName);
        } else {
            return "ReadNotPermits";
        }
    }


    /**
     * Ritorna il valore di un attributo chiamato per nome stto forma di stringa solo se l'utente ha i permessi di lettura
     * @param AttributeName Nome dell'attributo
     * @return Valore sotto forma di stringa
     * @throws Exception Attributo non trovato
     */
    @Override
    public String getAttributeValueToString(String AttributeName) throws Exception {
        if (this.isPermitsRead(AttributeName)) {
            return this.getAttributeValue(AttributeName).toString();
        } else {
            return "ReadNotPermits";
        }
    }

    /**
     * Permette di settare un attributo chiamandolo per nome solo se si hanno i permessi di modifica
     * @param AttributeName Nome dell'attributo
     * @param value valore dell'attributo
     * @throws Exception Attributo non trovato
     */
    @Override
    public void setAttributeValue(String AttributeName, Object value) throws Exception {
        if (this.isPermitsModify(AttributeName)) {
            super.setAttributeValue(AttributeName,value);
        }
    }

    /**
     * Permette di settare un attributo chiamandolo per nome senza vincoli di permessi
     * @param AttributeName Nome dell'attributo
     * @param value valore dell'attributo
     * @throws Exception Attributo non trovato
     */
    @Override
    public Object getAttributeValueNoLimits(String AttributeName)
            throws Exception {
        return super.getAttributeValueNoLimits(AttributeName);
    }

    /**
     * controlla se l'utente attualmente loggato ha i permessi di creazione per l'istanza di entity
     * @return TRUE = l'utente ha i permessi, FALSE = l'utente non ha i permessi
     */
    protected boolean isCreatable() {
        return super.howCreate().equals(group);
    }
}
